package sleuthkit.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.apache.log4j.Logger;

import sleuthkit.util.sleuthkit.processors.MmlsProcessor;
import sleuthkit.util.sleuthkit.processors.Processor;

public class Case {
	
	private static Logger log = Logger.getLogger(Case.class);
	private String caseName;
	private File caseFolder;
	private String investigator;
	private ArrayList<File> evidence = new ArrayList<File>();
	private ArrayList<File> memoryImage = new ArrayList<File>();
	private DefaultTreeModel explorerViewJTreeModel;
	private Processor processor = new MmlsProcessor();
	
	public Case() {
		StaticHelper.configLogger();
	}

	public Case(String caseName) {
		super();
		StaticHelper.configLogger();
		this.caseName = caseName;
	}

	public Case(String caseName, File caseFolder) {
		super();
		StaticHelper.configLogger();
		this.caseName = caseName;
		this.caseFolder = caseFolder;
	}

	public Case(String caseName, File caseFolder, String investigator) {
		super();
		StaticHelper.configLogger();
		this.caseName = caseName;
		this.caseFolder = caseFolder;
		this.investigator = investigator;
	}

	public Case(String caseName, File caseFolder, String investigator,
			ArrayList<File> evidence) {
		super();
		StaticHelper.configLogger();
		this.caseName = caseName;
		this.caseFolder = caseFolder;
		this.investigator = investigator;
		this.evidence = evidence;
	}

	/**
	 * @param log the log to set
	 */
	protected static void setLog(Logger log) {
		Case.log = log;
	}

	/**
	 * @param caseName the caseName to set
	 */
	protected void setCaseName(String caseName) {
		this.caseName = caseName;
	}

	/**
	 * @param caseFolder the caseFolder to set
	 */
	protected void setCaseFolder(File caseFolder) {
		this.caseFolder = caseFolder;
	}

	/**
	 * @param investigator the investigator to set
	 */
	protected void setInvestigator(String investigator) {
		this.investigator = investigator;
	}

	/**
	 * @param evidence the evidence to set
	 */
	protected void setEvidence(File evidence) {
		this.evidence.add(evidence);
	}
	
	/**
	 * @param evidence the evidence to set
	 */
	protected void setNewEvidenceFiles(ArrayList<File> evidence) {
		this.evidence = evidence;
	}

	/**
	 * @param evidence the evidence to set
	 */
	protected void addEvidence(ArrayList<File> evidence) {
		this.evidence.addAll(evidence);
	}

	/**
	 * @return the log
	 */
	protected static Logger getLog() {
		return log;
	}

	/**
	 * @return the caseName
	 */
	protected String getCaseName() {
		return caseName;
	}

	/**
	 * @return the caseFolder
	 */
	protected File getCaseFolder() {
		return caseFolder;
	}

	/**
	 * @return the investigator
	 */
	protected String getInvestigator() {
		return investigator;
	}

	/**
	 * @return the evidence
	 */
	protected ArrayList<File> getEvidence() {
		return evidence;
	}

	public void addEvidenceFile(File file) {
		// TODO Auto-generated method stub
		evidence.add(file);
	}

	public void save() throws IOException {
		// TODO Auto-generated method stub
		Properties prop = new Properties();
		log.debug("setting property caseName " + caseName);
		prop.setProperty("caseName", caseName);
		log.debug("setting property caseFolder " + caseFolder.getAbsolutePath());
		prop.setProperty("caseFolder", caseFolder.getAbsolutePath());
		log.debug("setting property investigator " + investigator);
		prop.setProperty("investigator", investigator);
		log.debug("setting property evidence");
		prop.setProperty("evidence", saveEvidence());
		
		
		log.debug("saving the case");
		FileOutputStream fos = new FileOutputStream(caseFolder.getAbsoluteFile()+ StaticHelper.fileSeparator + ".configuration.file");
		prop.storeToXML(fos,"configuration file for case " + caseName);
	}

	private String saveEvidence() {
		StringBuilder sb = new StringBuilder();
		if (evidence != null && !evidence.isEmpty()){
			log.debug("evidence contains files");
			for (File file : evidence) {
				if (sb.length()!=0){
					log.debug("Adding a ; for file sepration");
					sb.append(";");
				}
				log.debug("Adding the file " + file.getAbsolutePath());
				sb.append(file.getAbsolutePath());
			}
			return sb.toString();
		}
		return "";
	}

	public void populateTree(JTree explorerViewJTree) {
		DefaultMutableTreeNode topNodeDefaultMutableTreeNode = new DefaultMutableTreeNode(caseName);
		log.debug("trying to create the tree view for the case " + caseName);
		//explorerViewJTreeModel = (DefaultTreeModel)explorerViewJTree.getModel();
		
		log.debug("adding imagefiles for the case " + caseName);
		for (File file : evidence ) {
			
			log.debug("adding the following file" + file.getName() +" to the JTree");
			DefaultMutableTreeNode fileDefaultMutableTreeNode = new DefaultMutableTreeNode(new Node(file));
						
			log.debug("mmls processing of " + file);
			processor.process(file,fileDefaultMutableTreeNode);
			
			topNodeDefaultMutableTreeNode.add(fileDefaultMutableTreeNode);
		}
		log.debug("create a new DefaultTreeModel to change the root element");
		explorerViewJTreeModel = new DefaultTreeModel(topNodeDefaultMutableTreeNode);
		// explorerViewJTreeModel.insertNodeInto(topNodeDefaultMutableTreeNode, (MutableTreeNode) explorerViewJTreeModel.getRoot(), 0);
		
		
		
		log.debug("Setting the new model.");
		explorerViewJTree.setModel(explorerViewJTreeModel);
	}

	public void addMemoryImage(ArrayList<File> listFiles) {
		memoryImage.addAll(listFiles);
	}
	
	
}
